package tt.dz.egobus.servicemanager.service.impl;

import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import tt.dz.egobus.api.exception.ResponseException;
import tt.dz.egobus.api.managerservice.manager.BusinessBaseLimitStatus;
import tt.dz.egobus.base.dao.BaseDao;
import tt.dz.egobus.bean.BusinessStatus;
import tt.dz.egobus.servicemanager.base.service.AbstractExtendService;
import tt.dz.egobus.servicemanager.business.point.AddressPoint;
import tt.dz.egobus.servicemanager.business.point.BusPoint;
import tt.dz.egobus.servicemanager.dao.BusinessServiceDao;
import tt.dz.egobus.servicemanager.entities.BusinessService;
import tt.dz.egobus.servicemanager.entities.BusinessServiceInfo;
import tt.dz.egobus.servicemanager.entities.DriverRegisterBusRelative;
import tt.dz.egobus.servicemanager.service.BusRegisterServiceService;
import tt.dz.egobus.servicemanager.service.BusinessServiceInfoService;
import tt.dz.egobus.servicemanager.service.BusinessServiceService;
import tt.dz.egobus.servicemanager.vo.BusinessFinishVo;
import tt.dz.egobus.servicemanager.vo.BusinessRequestVo;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static tt.dz.egobus.bean.I18NCodeEnum.RPC_SYSTEM_CODE_ERROR;

/**
 * @author Anson
 * @date 17-3-15
 * @name 业务服务层实现
 * @since 1.0.3
 */
@Service("businessServiceServiceImpl")
public class BusinessServiceServiceImpl extends AbstractExtendService<BusinessService, String> implements
        BusinessServiceService {

    private static final Logger LOGGER = LoggerFactory.getLogger(BusinessServiceServiceImpl.class);


    @Autowired
    @Qualifier("businessServiceDaoImpl")
    private BusinessServiceDao dao;


    @Autowired
    @Qualifier("busRegisterServiceServiceImpl")
    private BusRegisterServiceService busRegisterServiceService;

    @Autowired
    @Qualifier("businessServiceInfoServiceImpl")
    private BusinessServiceInfoService businessServiceInfoService;

    @Override
    protected BaseDao<BusinessService, String> getSelfDao() {
        return this.dao;
    }

    @Override
    @Transactional
    public boolean doSaveBeginBusiness(DriverRegisterBusRelative relative, String businessId, String userId, BusPoint
            busPoint, BusinessRequestVo businessRequestVo) {

        if (null == relative || StringUtils.isEmpty(businessId) || busPoint == null || businessRequestVo == null) {
            return false;
        }
        LOGGER.info("业务服务层处理doSaveBeginBusiness");
        String relativeId = relative.getId();
        if (StringUtils.isEmpty(relativeId)) {
            return false;
        }

        BusinessService businessService = new BusinessService();
        businessService.setIsValidate(true);
        businessService.setAbleBeginBusiness();
        businessService.setServiceRegisterId(relativeId);
        businessService.setDriverId(relative.getDriverId());
        businessService.setBusinessId(businessId);
        businessService.setUserId(userId);
        businessService.setBusinessCode(businessRequestVo.getBusinessCode());
        businessService.setIsRideSelf(businessRequestVo.getUserRequestContactInfo().userRideTypeBySelf());
        businessService.setRequestType(businessRequestVo.getUserRequestInfo().getType());
        try {
            //预设默认值
            double serviceFee = this.busRegisterServiceService.getServiceFeeByBusIdBusinessCode(relative.getBusId(),
                    businessRequestVo.getBusinessCode());
            businessService.setServiceFee(serviceFee);
            this.dao.save(businessService);
            this.businessServiceInfoService.saveBeginBusinessService(businessService, busPoint, businessRequestVo,
                    relative);
            return true;
        } catch (Exception e) {
            LOGGER.error("创建业务保存数据库错误",e);
            return false;
        }
    }

    @Override
    @Transactional
    public BusinessService getBusinessByBusinessId(String businessId) {
        if (StringUtils.isEmpty(businessId)) {
            return null;
        }
        List<BusinessService> list = this.getBusinessListByBusinessId(businessId);
        return CollectionUtils.isEmpty(list) ? null : list.get(0);
    }

    @Override
    @Transactional
    public boolean validateBusinessId(String businessId) {
        List<BusinessService> list = this.getBusinessListByBusinessId(businessId);
        return (!CollectionUtils.isEmpty(list)) && list.size() == 1;
    }

    @Override
    @Transactional
    public boolean doSaveBusiness(String businessId, AddressPoint addressPoint) {
        BusinessService businessService = this.getBusinessByBusinessId(businessId);
        if (businessService == null) {
            return false;
        }
        businessService.setAbleBusiness();
        try {
            this.dao.update(businessService);
            //当前不更新当前司机最新地址
            this.businessServiceInfoService.doSaveBusiness(businessService, addressPoint);
            return true;
        } catch (Exception e) {
            return false;
        }
    }

    @Override
    @Transactional
    public boolean doSaveFinish(BusinessService businessService, BusinessFinishVo vo) {
        if (businessService == null) {
            return false;
        }
        businessService.setAbleFinish();
        businessService.setAbleUnPay();
        try {
            BusinessServiceInfo info = this.businessServiceInfoService.getInfoByServiceId(businessService.getId());
            BusinessBaseLimitStatus status = null;
            if (info != null) {
                status = info.getLimitStatus();
                if (status != null) {
                    businessService.setIsOverTime(status.getIsOverBaseTimeLimit());
                }
            }
            this.dao.update(businessService);
            //更新详细信息
            this.businessServiceInfoService.doSaveFinish(info, status, businessService, vo);
            return true;
        } catch (Exception e) {
            return false;
        }
    }

    @Override
    @Transactional
    public boolean doSaveUserCancel(BusinessService businessService) {
        if (businessService == null) {
            return false;
        }
        businessService.setAbleCancal();
        try {
            this.dao.update(businessService);
            return true;
        } catch (Exception e) {
            return false;
        }
    }

    @Override
    @Transactional
    public boolean modifyBusinessOrderStatus(BusinessService businessService, String orderId, int status, Double
            orderMoney) {
        if (businessService == null || StringUtils.isEmpty(orderId)) {
            return false;
        }
        businessService.setOrderId(orderId);
        businessService.setOrderStatus(status);
        if (null != orderMoney) {
            businessService.setServiceFee(orderMoney);
        }
        try {
            this.dao.update(businessService);
            return true;
        } catch (Exception e) {
            return false;
        }
    }

    @Override
    @Transactional
    public boolean isExitUserUnDoneBusiness(String userId) {
        return this.dao.isExitUserUnDoneBusiness(userId);

    }

    @Override
    @Transactional
    public BusinessService getUserUnDoneService(String userId) {
        return this.dao.getUserUnDoneService(userId);
    }

    @Override
    @Transactional
    public BusinessService getDriverUnDoneService(String driverId) {
        return this.dao.getDriverUnDoneService(driverId);
    }

    @Override
    @Transactional
    public BusinessService getBusinessByOrderId(String orderId) {
        List<BusinessService> list = this.getBusinessList(null, orderId);
        return CollectionUtils.isEmpty(list) ? null : list.get(0);
    }

    @Override
    @Transactional
    public Integer getDriverBusinesCount(String driverId) {
        Map<String, Object> params = new HashMap<String, Object>();
        params.put("eq#isValidate", true);
        params.put("eq#status", BusinessStatus.FINISH.getCode());
        if (!StringUtils.isEmpty(driverId)) {
            params.put("eq#driverId", driverId);
        }
        return this.dao.count(params);
    }

    @Override
    @Transactional
    public Integer[] queryDriverBusinessCodeCount(Integer[] businessCodes, String driverId) {
        if (businessCodes == null) {
            return new Integer[0];
        }
        Integer[] arrays = new Integer[businessCodes.length];
        List<Integer> counts = this.dao.queryDriverBusinessCodeCount(businessCodes, driverId);
        return counts == null ? arrays : counts.toArray(arrays);
    }

    @Transactional
    @Override
    public boolean doBespeakBusiness(DriverRegisterBusRelative relative, String businessId, String driverId, BusPoint
            busPoint, BusinessRequestVo businessRequestVo) {
        if (null == relative || StringUtils.isEmpty(businessId) || busPoint == null || businessRequestVo == null) {
            return false;
        }
        LOGGER.info("业务服务层处理doSaveBeginBusiness");
        String relativeId = relative.getId();
        if (StringUtils.isEmpty(relativeId)) {
            return false;
        }
        int businessCode = businessRequestVo.getBusinessCode();
        BusinessService businessService = new BusinessService();
        businessService.setIsValidate(true);
        businessService.setServiceRegisterId(relativeId);
        businessService.setDriverId(driverId);
        businessService.setBusinessId(businessId);
        businessService.setUserId(businessRequestVo.getUserId());
        businessService.setBusinessCode(businessCode);
        businessService.setIsRideSelf(businessRequestVo.getUserRequestContactInfo().userRideTypeBySelf());
        businessService.setAbleBespeakSuccess();
        businessService.setRequestType(businessRequestVo.getUserRequestInfo().getType());
        try {
            //预设默认值
            double serviceFee = this.busRegisterServiceService.getServiceFeeByBusIdBusinessCode(relative.getBusId(),
                    businessRequestVo.getBusinessCode());
            businessService.setServiceFee(serviceFee);
            this.dao.save(businessService);
            this.businessServiceInfoService.doBespeakBusiness(businessService, busPoint, businessRequestVo, relative);
            return true;
        } catch (Exception e) {
            throw new ResponseException(RPC_SYSTEM_CODE_ERROR);
        }
    }

    @Override
    @Transactional
    public boolean bespeakToBusiness(BusinessService businessService, DriverRegisterBusRelative relative) {
        businessService.setServiceRegisterId(relative.getId());
        businessService.setAbleBeginBusiness();
        try {
            this.dao.update(businessService);
            return true;
        } catch (Exception e) {
            return false;
        }
    }

    @Override
    @Transactional
    public boolean bespeakCancel(BusinessService businessService, BusinessServiceInfo businessServiceInfo) {
        businessService.setStatus(BusinessStatus.BESPEAK_CANCEL.getCode());
        try {
            this.dao.update(businessService);
            return true;
        } catch (Exception e) {
            return false;
        }
    }

    @Transactional
    @Override
    public boolean driverCancelBusiness(BusinessService businessService) {
        businessService.setStatus(BusinessStatus.CANCEL.getCode());
        try {
            this.dao.update(businessService);
            return true;
        } catch (Exception e) {
            return false;
        }
    }


    @Transactional
    private List<BusinessService> getBusinessListByBusinessId(String businessId) {
        return this.getBusinessList(businessId, null);
    }

    @Transactional
    private List<BusinessService> getBusinessList(String businessId, String orderId) {
        Map<String, Object> params = new HashMap<String, Object>();
        params.put("eq#isValidate", true);
        if (!StringUtils.isEmpty(orderId)) {
            params.put("eq#orderId", orderId);
        }
        if (!StringUtils.isEmpty(businessId)) {
            params.put("eq#businessId", businessId);
        }
        List<BusinessService> list = this.dao.list(params);
        return list;
    }


}
